package cn.topcodes.tcsf.admin.web.controller.impl;

import cn.topcode.unicorn.utils.I18nUtil;
import cn.topcode.unicorn.utils.IpUtil;
import cn.topcode.unicorn.utils.StringUtil;
import cn.topcode.unicorn.utils.ValidationUtil;
import cn.topcodes.tcsf.admin.commons.domain.ValueRangeConstant;
import cn.topcodes.tcsf.admin.commons.api.domain.ApiResponseEntity;
import cn.topcodes.tcsf.admin.domain.entity.SysMenu;
import cn.topcodes.tcsf.admin.domain.entity.SysUser;
import cn.topcodes.tcsf.admin.domain.form.ModifySysUserForm;
import cn.topcodes.tcsf.admin.domain.form.UpdateSysUserForm;
import cn.topcodes.tcsf.admin.service.res.SysMenuService;
import cn.topcodes.tcsf.admin.service.org.SysUserService;
import cn.topcodes.tcsf.admin.commons.api.security.ShiroUtil;
import com.google.common.base.Strings;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.util.List;

@Controller
@RequestMapping("/admin")
public class PersonalController {
	
	/*登录失败次数存储标记名称*/
	public static final String LOGIN_FAILED_TIMES_FLAG = "LOGIN_FAILED_TIMES_FLAG";
	
	/*登录失败次数内无需校验验证码*/
	public static final int LOGIN_FAILED_TIMES_NO_CAPTCHA = 3;
	
	@Autowired
	private SysUserService userService;
	
	@Autowired
	private SysMenuService menuService;

	/**
	 * 修改密码
	 * @param orginalPassword	原密码
	 * @param newPassword		新密码
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value="modify-password",method=RequestMethod.POST)
	public ApiResponseEntity<Void> modifyPassword(
			@RequestParam(required=true) String orginalPassword,
			@RequestParam(required=true) String newPassword
			) {
		this.userService.modifyPassword(ShiroUtil.getUserId(), orginalPassword, newPassword);

		return ApiResponseEntity.buildOK();
	}

	@ResponseBody
	@RequestMapping(value="modify-userinfo",method=RequestMethod.POST)
	public ApiResponseEntity<Void> modifyUserInfo(
			@Valid ModifySysUserForm form, BindingResult result
	) {
		ValidationUtil.validate(result);
		SysUser sysUser = this.userService.findOneOrFail(ShiroUtil.getUserId());
		sysUser.setRealName(form.getRealName());
		sysUser.setEmail(form.getEmail());
		sysUser.setTel(form.getTel());
		sysUser.setGender(form.getGender());
		this.userService.update(sysUser);
		return ApiResponseEntity.buildOK();
	}
	
	/**
	 * 管理登录请求入口
	 * @param username	用户名
	 * @param password	密码
	 * @param captcha	验证码，输错第3次才需验证
	 * @param rememberMe	记住密码，重启浏览器可通过cookie快速登录
	 */
	@ResponseBody
	@RequestMapping(value="login",method=RequestMethod.POST)
	public ApiResponseEntity<Void> login(
			HttpServletRequest request,
			@RequestParam(required=true) String username,
			@RequestParam(required=true) String password,
			@RequestParam(required=false) String captcha,
			@RequestParam(required=false,defaultValue="false") Boolean rememberMe
			) {
		HttpSession session = request.getSession();
		
		Subject subject = SecurityUtils.getSubject();
		if(subject.isAuthenticated()) {
			return ApiResponseEntity.buildFailed("您已登录");
		}
		Integer times = (Integer) session.getAttribute(LOGIN_FAILED_TIMES_FLAG);
		times = times == null ? 0 : times;
		if(/*times >= LOGIN_FAILED_TIMES_NO_CAPTCHA*/false) {
			//	登录失败次数过多则对比验证码
			String kaptchaExpected = (String) session.getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
			if (Strings.isNullOrEmpty(captcha) || !captcha.equalsIgnoreCase(kaptchaExpected)) {
				return ApiResponseEntity.buildIllegalArgument("登录失败！验证码输入错误");
			}
		}
		
		String ip = IpUtil.getIp(request);
		try {
			UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe);
			subject.login(token);
			userService.login(username, password, rememberMe,ip);
			//	登录成功清除登录失败次数
			session.removeAttribute(LOGIN_FAILED_TIMES_FLAG);
			
			return ApiResponseEntity.buildOK();
		}catch(AuthenticationException e) {
			//	登录失败次数+1
			times ++;
			session.setAttribute(LOGIN_FAILED_TIMES_FLAG, times);
			return ApiResponseEntity.buildIllegalArgument("登录失败！用户名或密码输入错误");
		}
	}
	
	@ResponseBody
	@RequestMapping(value="menu",method=RequestMethod.GET)
	public List<SysMenu> adminMenu(HttpServletRequest request) {
		boolean isDeveloper = false;
		Subject subject = SecurityUtils.getSubject();
		if(subject.hasRole(ValueRangeConstant.BuiltInRole.ROLE_DEVELOPER)) {
			isDeveloper = true;
		}
		List<SysMenu> menus = this.menuService.findPermedMenu(ShiroUtil.getUserId(), isDeveloper);
		i18nMenus(menus, request);
		return menus;
	}

	public void i18nMenus(List<SysMenu> menus, HttpServletRequest request) {
		for(SysMenu sysMenu : menus) {
			if(StringUtil.isNotBlank(sysMenu.getI18n())) {
				sysMenu.setName(I18nUtil.getMessage(request, sysMenu.getI18n()));
			}
		}
	}
	
	/**
	 * 管理登出请求入口
	 */
	@ResponseBody
	@RequestMapping(value="logout",method=RequestMethod.POST)
	public ApiResponseEntity<Void> logout() {
		Subject subject = SecurityUtils.getSubject();
		subject.logout();
		userService.logout();
		return ApiResponseEntity.buildOK();
	}
}
